<rows>For the variant with dynamic loading it gets two additional parameters and (as far as we should process some incoming arguments) needs to be created dynamically with some server side programming language:
<row id="xx">
<cell>
...
</cell>
</row>
</rows>
<rows total_count="x" pos="y">Thus, this tutorial is not just about JavaScript, but also about server side a little. I'll show you server side code for PHP, ASP, JSP, ColdFusion. But let's do everything in its turn.
<row id="xx">
<cell>
...
</cell>
</row>
</rows>
<link rel="STYLESHEET" type="text/css" href="codebase/dhtmlxgrid.css">
<script src="codebase/dhtmlxcommon.js"></script>
<script src="codebase/dhtmlxgrid.js"></script>
<script src="codebase/dhtmlxgridcell.js"></script>
<script src="codebase/ext/dhtmlxgrid_srnd.js"></script>
<script>
var gridQString = "";//we'll save here the last url with query string we used for loading grid (see step 5 for details)
//we'll use this script block for functions
</script>
As you probably remember from the previous chapter, I used body "onload" event to call grid initialization function. The code mentioned above is another case as it calls script methods on the page placing them after DIV container we want to place our grid into. The goal here is the same: to call the grid constructor after the DIV container was initialized.<div id="products_grid" style="width:500px;height:200px;"></div>
<script>
var mygrid = new dhtmlXGridObject('products_grid');mygrid.setImagePath("codebase/imgs/");
mygrid.setHeader("Product Name,Internal Code,Price");
mygrid.setInitWidths("*,150,150");
mygrid.setColAlign("left,left,right");
mygrid.setSkin("modern");
mygrid.init();
mygrid.enableSmartRendering(true);
</script>

gridQString = "getGridRecords.php";//save query string to global variable (see step 5 for details)Sending the request to the URL you specify inside loadXML method, grid adds two properties:
mygrid.loadXML(gridQString );
<?php
//set content type and xml tag
header("Content-type:text/xml");
print("<?xml version=\"1.0\"?>");
//define variables from incoming values
if(isset($_GET["posStart"]))
$posStart = $_GET['posStart'];
else
$posStart = 0;
if(isset($_GET["count"]))
$count = $_GET['count'];
else
$count = 100;
//connect to database
$link = mysql_pconnect("localhost", "user", "pwd");
$db = mysql_select_db ("sampleDB");
//create query to products table
$sql = "SELECT * FROM products";
//if this is the first query - get total number of records in the query result
if($posStart==0){
$sqlCount = "Select count(*) as cnt from ($sql) as tbl";
$resCount = mysql_query ($sqlCount);
$rowCount=mysql_fetch_array($resCount);
$totalCount = $rowCount["cnt"];
}
//add limits to query to get only rows necessary for the output
$sql.= " LIMIT ".$posStart.",".$count;
//query database to retrieve necessary block of data
$res = mysql_query ($sql);
//output data in XML format
print("<rows total_count='".$totalCount."' pos='".$posStart."'>");
while($row=mysql_fetch_array($res)){
print("<row id='".$row['id']."'>");
print("<cell>");
print($row['nm']); //value for product name
print("</cell>");
print("<cell>");
print($row['code']); //value for internal code
print("</cell>");
print("<cell>");
print($row['num_val']); //value for price
print("</cell>");
print("</row>");
}
print("</rows>");
?>
* - sample code was simplified to concentrate you on the main commands. Some necessary error handlers etc. were omitted.
<%@ page import = "java.sql.*" %>
<%
String db_ipp_addr = "localhost";
String db_username = "root";
String db_password = "1";
String db_name = "sampleDB";
// set content type and xml tag
response.setContentType("text/xml");
out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
// define variables from incoming values
String posStart = "";
if (request.getParameter("posStart") != null){
posStart = request.getParameter("posStart");
}else{
posStart = "0";
}
String count = "";
if (request.getParameter("count") != null){
count = request.getParameter("count");
}else{
count = "100";
}
// connect to database
Connection connection = null;
Statement statement = null;
ResultSet rs = null;
String connectionURL = "jdbc:mysql://" + db_ipp_addr + ":3306/" + db_name;
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = DriverManager.getConnection(connectionURL, db_username, db_password);
// query to products table
String sql = "SELECT * FROM products";
// if this is the first query - get total number of records in the query result
String totalCount = "";
if (posStart.equals("0")){
String sqlCount = "Select count(*) as cnt from (" + sql + ") as tbl";
statement = connection.createStatement();
rs = statement.executeQuery(sqlCount);
rs.next();
totalCount = rs.getString("cnt");
rs.close();
} else {
totalCount = "";
}
// add limits to query to get only rows necessary for output
sql += " LIMIT " + posStart + "," + count;
// Execute the query
statement = connection.createStatement();
rs = statement.executeQuery(sql);
// output data in XML format
out.println("<rows total_count='" + totalCount + "' pos='" + posStart + "'>");
while (rs.next()) {
out.println("<row id='" + rs.getString("id") + "'>");
out.println("<cell>");
out.println(rs.getString("nm")); // value for product name
out.println("</cell>");
out.println("<cell>");
out.println(rs.getString("code")); // value for internal code
out.println("</cell>");
out.println("<cell>");
out.println(rs.getString("num_val")); // value for price
out.println("</cell>");
out.println("</row>");
}
out.write("</rows>");
rs.close();
%>
<%@ LANGUAGE = VBScript %>
<% option explicit %>
<%
Dim db_ipp_addr, db_username, db_password, db_name
db_ipp_addr = "localhost"
db_username = "root"
db_password = "1"
db_name = "sampleDB"
' set content type and xml tag
Response.ContentType = "text/xml"
Response.write("<?xml version=""1.0"" encoding=""UTF-8""?>")
' define variables from incoming values
Dim posStart, count
If not isEmpty(Request.QueryString("posStart")) Then
posStart = Request.QueryString("posStart")
Else
posStart = 0
End If
If not isEmpty(Request.QueryString("count")) Then
count = Request.QueryString("count")
Else
count = 100
End If
' connect to database
Dim objConnection, rs, connString, sql
Set objConnection = Server.CreateObject("ADODB.Connection")
Set rs = Server.CreateObject("ADODB.Recordset")
connString = "DRIVER={MySQL ODBC 3.51 Driver}; SERVER=" & db_ipp_addr & "; DATABASE=" & db_name & "; UID=" & db_username & "; PWD=" & db_password
objConnection.Open connString
' query to products table
sql = "SELECT * FROM products"
' if this is the first query - get total number of records in the query result
Dim sqlCount, totalCount
If posStart = 0 Then
sqlCount = "Select count(*) as cnt from (" & sql & ") as tbl"
rs.Open sqlCount, objConnection
totalCount = rs("cnt")
rs.Close
Else
totalCount = ""
End If
' add limits to query to get only rows necessary for output
sql = sql & " LIMIT " & posStart & "," & count
' Execute the query
rs.Open sql, objConnection
' output data in XML format
Response.write("<rows total_count='" & totalCount & "' pos='" & posStart & "'>")
Do while not rs.EOF
Response.write("<row id='" & rs("id") & "'>")
Response.write("<cell>")
Response.write(rs("nm")) ' value for product name
Response.write("</cell>")
Response.write("<cell>")
Response.write(rs("code")) ' value for internal code
Response.write("</cell>")
Response.write("<cell>")
Response.write(rs("num_val")) ' value for price
Response.write("</cell>")
Response.write("</row>")
rs.MoveNext
Loop
Response.write("</rows>")
rs.Close
Set rs = Nothing
objConnection.Close
Set objConnection = Nothing
%>
<cfset dsn = "sampleDB">
<cfsetting enablecfoutputonly="yes">
<!--- set content type and xml tag --->
<cfcontent reset="yes" type="text/xml; charset=UTF-8"><cfoutput><?xml version="1.0"?></cfoutput>
<!--- define variables from incoming values --->
<cfif isDefined("url.posStart")>
<cfset posStart = url.posStart>
<cfelse>
<cfset posStart = 0>
</cfif>
<cfif isDefined("url.count")>
<cfset count = url.count>
<cfelse>
<cfset count = 100>
</cfif>
<!--- if this is the first query - get total number of records in the query result --->
<cfif posStart eq 0>
<cfquery datasource="#dsn#" name="getCount">
Select count(*) as cnt
FROM products
</cfquery>
<cfset totalCount = getCount.cnt>
<cfelse>
<Cfset totalCount = "">
</cfif>
<!--- query to products table --->
<cfquery datasource="#dsn#" name="getRecords">
SELECT *
FROM products
<!--- add limits to query to get only rows necessary for output --->
LIMIT #posStart#, #count#
</cfquery>
<!--- output data in XML format --->
<cfoutput><rows total_count="#totalCount#" pos="#posStart#"></cfoutput>
<cfloop query="getRecords">
<cfoutput><row id="#getRecords.id#"></cfoutput>
<!--- value for product name --->
<cfoutput><cell>#getRecords.nm#</cell></cfoutput>
<!--- value for internal code --->
<cfoutput><cell>#getRecords.code#</cell></cfoutput>
<!--- value for price --->
<cfoutput><cell>#getRecords.num_val#</cell></cfoutput>
<cfoutput></row></cfoutput>
</cfloop>
<cfoutput></rows></cfoutput>
After loading the file the grid will look something like in the picture below. When you stop scrolling the grid will load and draw a new portion of records.

<input type="Text" id="nm_mask">As you see, clicking the "Filter" button we call applyFilter function, which doesn't exist as we haven't created it yet. Let's do it now. It will contain the magic of getting the content for grid based on additional parameter :)
<input type="Button" value="Filter" onclick="applyFilter()">
function applyFilter(){Put it into the script block we left for functions (or any other - it doesn't matter).
mygrid.clearAll(); //remove all data
gridQString = "getGridRecords.php?name_mask="+document.getElementById("nm_mask").value;//save query string in global variable (see step 5 for details)
mygrid.loadXML(gridQString); // load new dataset from sever with additional parameter passed
}
//query to products table
$sql = "SELECT * FROM products";
if(isset($_GET["name_mask"]))
$sql.=" Where nm like '".$_GET["name_mask"]."%'";
mygrid.setColSorting("server,server,server");The "server" sorting type means nothing for sorting routine of the grid, so it'll just ignore it. This information is mostly for myself as column sorting was moved to server side. Put this command somewhere before mygrid.init() .
function sortGridOnServer(ind,gridObj,direct){The above mentioned code does the following:
mygrid.clearAll();
mygrid.loadXML(gridQString+(gridQString.indexOf("?")>=0?"&":"?")+"orderby="+ind+"&direct="+direct);
mygrid.setSortImgState(true,ind,direct);
return false;
}
mygrid.attachEvent("onBeforeSorting",sortGridOnServer);Server side changes are simple, as we just add Order by statement for the field in table that corresponds to a column in grid, and set the direction: ASC if asc, DESC if des.
//order by
$columns = array("nm","code","num_val");
if(isset($_GET["orderby"])){
if($_GET["direct"]=='des')
$direct = "DESC";
else
$direct = "ASC";
$sql.=" Order by ".$columns[$_GET["orderby"]]." ".$direct;
}